var revenueApi = require('../../script/revenue.js');
var config = require('../../script/config.js');
const App = getApp();
import drawQrcode from 'weapp-qrcode'
const iconv = require('iconv-lite');
import {
  parseTime
} from '../../utils/util';
var timer;
Page({

  /**
   * 页面的初始数据
   */
  data: {
    userinfo: null,
    payInfo: {
      CONS_NO: '',
      CONS_NAME: '',
      QRCode: '',
      OrderNo: '',
      OrderMoney: 0,
      DiscountCost: 0,
      DelayCost: 0,
      AccountMoney: 0,
      ExpireTime: ''
    },
    qrcodeImagePath: '',
    currentDevice: null,
    deviceId: null,
    serviceId: null,
    characteristicId: null,
    ShowPop: false,
    isSearching: false,
    isConnecting: false,
    isConnected: false,
    unicodeToGbkMap: {},
    OrderInfo: null
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.getUserInfo()
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {
    const eventChannel = this.getOpenerEventChannel()
    eventChannel.on('sendmessage', (data) => {
      this.setData({
        payInfo: data.data
      });
      this.createQrcode();
    })
    this.InitBluetooth();
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    wx.closeBLEConnection();
    wx.closeBluetoothAdapter();
    if (this.timer) {
      clearTimeout(this.timer);
    }
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  },
  getUserInfo: function () {
    try {
      var value = wx.getStorageSync(config.storageKey.userinfo)
      if (value) {
        this.setData({
          userinfo: value
        })
      }
    } catch (e) {
      // Do something when catch error
    }
  },
  createQrcode() {
    drawQrcode({
      width: 200,
      height: 200,
      canvasId: 'qrcodeCanvas',
      text: this.data.payInfo.QRCode,
      correctLevel: 2,
      image: {
        imageResource: '../../images/logo_s.png',
        dx: 75,
        dy: 75,
        dWidth: 50,
        dHeight: 50
      }
    });
    setTimeout(() => {
      wx.canvasToTempFilePath({
        quality: 1,
        fileType: 'jpg',
        canvasId: 'qrcodeCanvas',
        destWidth: 200 * App.globalData.pixelRatio,
        destHeight: 200 * App.globalData.pixelRatio,
        width: 200,
        height: 200,
        success: (res) => {
          this.setData({
            qrcodeImagePath: res.tempFilePath
          });
        },
        fail: function (res) {

        }
      }, this)
    }, 200)
  },
  getTime() {
    const now = new Date();
    now.setDate(now.getDate() + 1);
    this.setData({
      time: parseTime(now, 'yyyy-MM-dd') + ' 23:59:59'
    });
  },
  Save() {
    // this.setData({
    //   ShowPop: true,
    // });
    // return;
    wx.showLoading({
      title: '校验缴费中...',
      mask: true
    });

    revenueApi.CheckQROrder(this.data.payInfo.OrderNo).then(res => {
      if (res.code === 200) {
        this.setData({
          OrderInfo: res.data
        });
        wx.hideLoading();
        this.setData({
          ShowPop: true,
        });
      } else {
        wx.showToast({
          title: res.info,
          icon: 'none'
        });
      }
    })
  },
  // 第一步 初始化蓝牙适配器
  InitBluetooth() {
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('初始化蓝牙适配器成功', res);
        wx.showToast({
          title: '初始化蓝牙适配器成功',
          icon: 'none'
        });
        this.SearchDevices();
      },
      fail: (err) => {
        console.error('初始化蓝牙适配器失败', err);
        wx.showToast({
          title: '请检查手机蓝牙是否开启',
          icon: 'none'
        });
      }
    });
  },
  // 第二步 搜索设备
  SearchDevices() {
    clearTimeout(this.timer);
    this.timer = null;
    this.setData({
      isSearching: true,
      currentDevice: null
    });
    wx.startBluetoothDevicesDiscovery({
      // allowDuplicatesKey: false,
      services: ['E7810A71-73AE-499D-8C15-FAA9AEF0C3F2'], // 只搜索主服务 UUID 为 XXX 的设备
      success: (res) => {
        console.log('开始搜索', res);
      },
      fail: (err) => {
        this.setData({
          isSearching: false,
        });
        console.log('startBluetoothDevicesDiscovery调用失败', err);
        /* 错误处理 */
      },
      complete: () => {
        console.log('startBluetoothDevicesDiscovery调用结束');
      }
    });
    // 监听寻找到新设备的事件
    wx.onBluetoothDeviceFound((res) => {
      console.log('发现设备');
      wx.showToast({
        title: '发现蓝牙设备',
        icon: 'none'
      });
      const devices = res.devices;
      console.log(devices);
      wx.stopBluetoothDevicesDiscovery(); // 停止搜索
      this.setData({
        isSearching: false,
        currentDevice: devices[0]
      });
      this.ConnectToDevice();
    });
    this.timer = setTimeout(() => {
      wx.stopBluetoothDevicesDiscovery(); // 停止搜索
      this.setData({
        isSearching: false,
      });
    }, 30000)
  },
  // 第三步 连接设备
  ConnectToDevice() {
    if (this.data.isConnected) return;
    this.setData({
      isConnecting: true
    });
    wx.createBLEConnection({
      deviceId: this.data.currentDevice.deviceId,
      success: (res) => {
        console.log('蓝牙打印机连接成功', res);
        wx.showToast({
          title: '蓝牙打印机连接成功',
          icon: 'none'
        });
        this.setData({
          deviceId: this.data.currentDevice.deviceId,
          isConnecting: false,
          isConnected: true
        });
        // 连接成功后，获取设备服务
        this.GetDeviceServices();
      },
      fail: (err) => {
        this.setData({
          isConnecting: false
        });
        wx.showToast({
          title: '配对失败',
          icon: 'none'
        });
      }
    });
  },
  // 第四步 获取设备服务
  GetDeviceServices() {
    wx.getBLEDeviceServices({
      deviceId: this.data.deviceId,
      success: (res) => {
        const services = res.services;
        // 通常我们需要寻找特定的服务UUID，这里以第一个服务为例
        const targetService = services[0].uuid;
        this.setData({
          serviceId: targetService,
        });
        // 获取该服务下的所有特征值
        this.GetDeviceCharacteristics();
      },
      fail: (err) => {
        /* 错误处理 */
      }
    });
  },
  // 第五步 获取指定服务的特征值列表
  GetDeviceCharacteristics() {
    wx.getBLEDeviceCharacteristics({
      deviceId: this.data.deviceId,
      serviceId: this.data.serviceId,
      success: (res) => {
        const characteristics = res.characteristics;
        // 查找具有 write 属性的特征值，用于发送数据
        const writeChar = characteristics.find(char => char.properties.write);
        if (writeChar) {
          // 保存这个特征值的UUID，后续发送数据需要
          this.setData({
            characteristicId: writeChar.uuid
          });
        }
      },
      fail: (err) => {
        /* 错误处理 */
      }
    });
  },
  ReSearch() {
    // 1. 开始搜索前，先获取所有已发现的设备列表（关键步骤）
    wx.getBluetoothDevices({
      success: (res) => {
        const devices = res.devices;
        // 遍历设备列表，检查你的目标设备是否已经在其中
        if (devices.length > 0) {
          const targetDevice = devices.find(device => device.deviceId === this.data.deviceId); // 请替换为你的设备名称或识别条件
          if (targetDevice) {
            console.log('从缓存列表中找到设备', targetDevice);
            // 直接使用这个 device 进行连接
            this.setData({
              isSearching: false,
              currentDevice: targetDevice
            });
            this.ConnectToDevice();
            return; // 如果找到，可以考虑直接返回，不再启动新搜索，或者根据需求决定
          }
        }
        // 2. 如果缓存列表中没有，再启动发现新设备的监听
        this.SearchDevices();
      },
      fail: (err) => {
        if(err.errCode === 10002){
          // 没有找到指定设备
          this.SearchDevices();
        }else{
          this.InitBluetooth();
        }
      },
    })
  },
  Print() {
    if(!this.data.currentDevice){
      wx.showToast({
        title: '已重新搜索蓝牙设备',
        icon: 'none'
      });
      this.ReSearch();
      return;
    }
    if (!this.data.isConnected) {
      wx.showToast({
        title: '启动连接中，请稍后打印',
        icon: 'none'
      });
      this.ConnectToDevice();
      return;
    }
    wx.showLoading({
      title: '正在打印票据...',
      mask: true
    });
    // 初始化打印机 ESC @
    const initCmd = new Uint8Array([0x1B, 0x40]);
    // 设置居中 ESC a 1
    const alignCmd = new Uint8Array([0x1B, 0x61, 0x00]);
    const titleBytesGBK = iconv.encode("\t   采暖缴费单\n", 'gbk');
    const sep = this.getUint8Array("------------------------------------------------\n");
    const line = this.getUint8Array("\n\n");
    const CONS_NO = iconv.encode(`户    号: ${this.data.OrderInfo.ConsNo}\n`, 'gbk');
    const CONS_NAME = iconv.encode(`户    名: ${this.data.OrderInfo.ConsName}\n`, 'gbk');
    const Charge_Date = iconv.encode(`收款时间: ${this.data.OrderInfo.PayTime}\n`, 'gbk');
    const USER_NAME = iconv.encode(`收 费 员：${this.data.OrderInfo.OperatorName}\n`, 'gbk');
    const OrderNo = iconv.encode(`支付单号: ${this.data.OrderInfo.OrderNo}\n\n`, 'gbk');
    // const OrderNo = iconv.encode(`支付单号: 3GEA2025092510481701353\n\n`, 'gbk');
    const titleColumn = iconv.encode("年度\t单价\t供暖面积  应收金额\n", 'gbk');
    const details = [];
    for (let i = 0; i < this.data.OrderInfo.Detail.length; i++) {
      const item = this.data.OrderInfo.Detail[i];
      const itemValue = iconv.encode(`${item.HeatDuration}  ${item.Price}      ${item.HeatArea}      ${item.AccountMoney}\n`, 'gbk');
      details.push(...itemValue);
    }
    const OrderMoney = iconv.encode(`金额总计: ￥${this.data.OrderInfo.OrderMoney}\n`, 'gbk');
    const DiscountCost = iconv.encode(`优惠金额: ￥${this.data.OrderInfo.DiscountCost}\n`, 'gbk');
    const DelayCost = iconv.encode(`违 约 金: ￥${this.data.OrderInfo.DelayCost}\n`, 'gbk');
    const AccountMoney = iconv.encode(`实付金额: ￥${this.data.OrderInfo.AccountMoney}\n`, 'gbk');
    const payType = iconv.encode(`付    款: 线下扫码支付\n`, 'gbk');
    const company = iconv.encode(`${this.data.OrderInfo.CompanyName}\n`, 'gbk');
    const phone = iconv.encode(`客服热线：${this.data.OrderInfo.CompanyPhone}\n\n\nn\n`, 'gbk');

    // 合并所有指令和文本数据
    const fullBuffer = new Uint8Array([
      ...initCmd,
      ...alignCmd,
      ...line,
      ...titleBytesGBK,
      // 0x0D,
      ...sep,
      ...CONS_NO,
      ...CONS_NAME,
      ...Charge_Date,
      ...USER_NAME,
      ...OrderNo,
      ...sep,
      ...titleColumn,
      ...sep,
      ...details,
      ...sep,
      // ...line,
      ...OrderMoney,
      ...DiscountCost,
      ...DelayCost,
      ...AccountMoney,
      ...payType,
      ...sep,
      ...company,
      ...phone,
      0x1D, 0x56, 0x42, 0x00 // 全切纸指令（如果打印机支持）
    ]);
    this.DoPrintChunk(fullBuffer.buffer);
  },
  getUint8Array(str) {
    const buffer = new ArrayBuffer(str.length);
    const dataView = new Uint8Array(buffer);
    for (let i = 0; i < str.length; i++) {
      dataView[i] = str.charCodeAt(i);
    }
    return dataView;
  },
  DoPrintChunk(buffer) {
    const {
      deviceId,
      serviceId,
      characteristicId
    } = this.data;

    const MAX_PACKET_SIZE = 20; // 单次写入最大字节数，通常建议20字节[4](@ref)
    let offset = 0;
    const sendNext = () => {
      if (offset >= buffer.byteLength) {
        wx.hideLoading();
        return;
      };
      const packet = buffer.slice(offset, offset + MAX_PACKET_SIZE);
      offset += MAX_PACKET_SIZE;
      wx.writeBLECharacteristicValue({
        deviceId: deviceId,
        serviceId: serviceId,
        characteristicId: characteristicId,
        value: packet,
        success: (res) => {
          console.log('写入成功', res);
          sendNext();
        },
        fail: (err) => {
          wx.hideLoading();
          console.error('写入失败', err);
        }
      });
    }
    sendNext();
  },
  DoPrint(buffer) {
    // const text = '测试打印测试打印测试打印测试打印\n'
    // const command = this.formatPrintCommand(text);
    // // 2. 将字符串转换为 ArrayBuffer
    // const buffer = new ArrayBuffer(command.length);
    // const dataView = new Uint8Array(buffer);
    // for (let i = 0; i < command.length; i++) {
    //   dataView[i] = command.charCodeAt(i);
    // }

    const {
      deviceId,
      serviceId,
      characteristicId
    } = this.data;
    wx.writeBLECharacteristicValue({
      deviceId: deviceId,
      serviceId: serviceId,
      characteristicId: characteristicId,
      value: buffer,
      success: (res) => {
        wx.closeBLEConnection();
        wx.closeBluetoothAdapter();
        console.log('写入成功', res);
        wx.hideLoading();
      },
      fail: (err) => {
        console.error('写入失败', err);
      }
    });
  },
  addTextToCommand(commands, text) {
    for (let i = 0; i < text.length; i++) {
      commands.push(text.charCodeAt(i));
    }
  },
  formatPrintCommand(text) {
    // ESC/POS 指令示例：初始化打印机、设置文本、换行、切纸（如果有切刀）
    // 例如，设置字体大小、对齐方式，最后加入换行符等
    //打印机初始化：0x1B 0x40
    //设置对齐方式：
    //左对齐：0x1B 0x61 0x00
    //居中：0x1B 0x61 0x01
    //右对齐：0x1B 0x61 0x02

    //设置字体大小：
    //0x1D 0x21 0x00 - 正常大小
    //0x1D 0x21 0x11 - 双倍宽高

    //换行：0x0A

    //切纸：0x1D 0x56 0x42 0x00
    const initialize = '\x1B\x40'; // 初始化指令
    const lineFeed = '\x0A'; // 换行
    const cutPaper = '\x1D\x56\x00'; // 切纸指令（视打印机支持情况）

    return initialize + text + lineFeed + lineFeed + lineFeed + cutPaper;
  },
  // 打印完成后，及时调用 wx.closeBLEConnection和 wx.closeBluetoothAdapter释放资源
})